package handlers

import (
	"fmt"
	"github.com/coreos/go-iptables/iptables"
	"github.com/gin-gonic/gin"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/spf13/viper"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"sync"
)

var (
	ipList  = []map[string]interface{}{}
	ipMutex sync.Mutex
)

type Response struct {
	Status  int         `json:"status"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func LoginHandler(c *gin.Context) {
	var password = viper.GetString("server.pwd")
	var req struct {
		Password string `json:"password"`
	}
	if c.BindJSON(&req) != nil {
		c.JSON(http.StatusBadRequest, Response{0, "请求错误", nil})
		return
	}
	// fmt.Printf("pwd:%s", password)
	if req.Password == password {
		c.JSON(http.StatusOK, Response{1, "登录成功", nil})
	} else {
		c.JSON(http.StatusOK, Response{0, "密码错误", nil})
	}
}

/*
func SystemHandler(c *gin.Context) {
	c.JSON(http.StatusOK, Response{
		Status:  1,
		Message: "成功",
		Data: map[string]interface{}{
			"cpu":    "20%",
			"memory": "60%",
			"disk":   "50%",
		},
	})
}
*/

// SystemHandler 获取系统信息

// formatPercent 将浮点数格式化为百分比字符串
func formatPercent(value float64) string {
	return fmt.Sprintf("%.1f%%", value)
}

// SystemHandler 获取系统信息
func SystemHandler(c *gin.Context) {
	// 获取 CPU 使用率
	cpuPercent, err := cpu.Percent(0, false)
	if err != nil {
		c.JSON(http.StatusInternalServerError, Response{
			Status:  0,
			Message: "获取 CPU 信息失败",
			Data:    nil,
		})
		return
	}

	// 获取内存使用率
	memInfo, err := mem.VirtualMemory()
	if err != nil {
		c.JSON(http.StatusInternalServerError, Response{
			Status:  0,
			Message: "获取内存信息失败",
			Data:    nil,
		})
		return
	}

	// 获取磁盘使用率
	diskInfo, err := disk.Usage("/")
	if err != nil {
		c.JSON(http.StatusInternalServerError, Response{
			Status:  0,
			Message: "获取磁盘信息失败",
			Data:    nil,
		})
		return
	}

	// 返回结果，将数值格式化为百分比字符串
	c.JSON(http.StatusOK, Response{
		Status:  1,
		Message: "成功",
		Data: map[string]interface{}{
			"cpu":    formatPercent(cpuPercent[0]),        // CPU 使用率（百分比格式）
			"memory": formatPercent(memInfo.UsedPercent),  // 内存使用率（百分比格式）
			"disk":   formatPercent(diskInfo.UsedPercent), // 磁盘使用率（百分比格式）
		},
	})
}

func GetVOSPort(c *gin.Context) {
	var port = viper.GetString("vos.port")
	c.JSON(http.StatusOK, Response{
		Status:  1,
		Message: "处理成功",
		Data: map[string]interface{}{
			"port": port,
		},
	})
}

func VOSHandler(c *gin.Context) {
	var request struct {
		Port string `json:"port"`
	}
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, Response{0, "无效的请求参数", nil})
		return
	}
	// 获取客户端 IP 地址
	clientIP, err := getClientIP(c.Request)
	if err != nil {
		c.JSON(400, gin.H{"error": fmt.Sprintf("Failed to get client IP: %v", err)})
		return
	}
	// 校验端口号
	if !isValidPort(request.Port) {
		c.JSON(http.StatusBadRequest, Response{0, "端口号无效，必须是 1024-65535 之间的数字", nil})
		return
	}

	// 设置端口号
	viper.Set("vos.port", request.Port)
	if err := viper.WriteConfig(); err != nil {
		c.JSON(http.StatusInternalServerError, Response{0, "保存配置失败", nil})
		return
	}
	// 设置防火墙代码部分：
	// 添加 iptables 规则
	if err := addIPTablesRule(clientIP, request.Port); err != nil {
		c.JSON(500, gin.H{"error": fmt.Sprintf("Failed to add iptables rule: %v", err)})
		return
	}
	c.JSON(http.StatusOK, Response{1, "端口号设置成功", nil})
}

func DeleteIPHandler(c *gin.Context) {
	id := c.Param("id")
	fmt.Printf(id)
	// 示例删除逻辑（实际应根据id删除）
	ipMutex.Lock()
	defer ipMutex.Unlock()
	if len(ipList) > 0 {
		ipList = ipList[:len(ipList)-1]
	}
	c.JSON(http.StatusOK, Response{1, "删除成功", nil})
}

// 校验端口号是否有效
func isValidPort(port string) bool {
	// 检查是否为数字
	for _, c := range port {
		if c < '0' || c > '9' {
			return false
		}
	}

	// 检查范围
	portNum := 0
	fmt.Sscanf(port, "%d", &portNum)
	return portNum >= 1024 && portNum <= 65535
}

// 获取客户端 IP 地址
func getClientIP(r *http.Request) (string, error) {
	// 从 X-Forwarded-For 头部获取 IP（适用于反向代理场景）
	ip := r.Header.Get("X-Forwarded-For")
	if ip != "" {
		return strings.Split(ip, ",")[0], nil
	}

	// 直接从 RemoteAddr 获取 IP
	host, _, err := net.SplitHostPort(r.RemoteAddr)
	if err != nil {
		return "", fmt.Errorf("invalid RemoteAddr: %v", err)
	}
	return host, nil
}

// 添加 iptables 规则
func addIPTablesRule(ip string, port string) error {
	// 初始化iptables
	ipt, err := iptables.New()
	if err != nil {
		return fmt.Errorf("初始化iptables失败: %v", err)
	}

	// 添加规则
	err = ipt.AppendUnique("filter", "INPUT", "-p", "tcp", "--dport", port, "-s", ip, "-j", "ACCEPT")
	if err != nil {
		return fmt.Errorf("添加iptables规则失败: %v", err)
	}

	log.Printf("Added iptables rule for IP: %s\n", ip)
	return nil
}

// GetVOSIdentifier 获取VOS系统标识
func GetVOSIdentifier(c *gin.Context) {
	// 尝试读取第一个配置文件路径
	filePath1 := "/home/kunshi/vos3000/etc/server.conf"
	file, err := os.ReadFile(filePath1)
	if err != nil {
		// 如果第一个路径读取失败，尝试第二个路径
		filePath2 := "/home/kunshi/vos3000/server/etc/server.conf"
		file, err = os.ReadFile(filePath2)
		if err != nil {
			c.JSON(http.StatusInternalServerError, Response{
				Status:  0,
				Message: "读取配置文件失败",
				Data:    nil,
			})
			return
		}
	}

	// 解析文件内容，查找ACCESS_UUID字段
	lines := strings.Split(string(file), "\n")
	var accessUUID string
	for _, line := range lines {
		if strings.HasPrefix(strings.TrimSpace(line), "ACCESS_UUID=") {
			parts := strings.Split(line, "=")
			if len(parts) > 1 {
				accessUUID = strings.TrimSpace(parts[1])
				break
			}
		}
	}

	if accessUUID == "" {
		c.JSON(http.StatusInternalServerError, Response{
			Status:  0,
			Message: "未找到系统标识",
			Data:    nil,
		})
		return
	}

	c.JSON(http.StatusOK, Response{
		Status:  1,
		Message: "获取成功",
		Data: map[string]interface{}{
			"identifier": accessUUID,
		},
	})
}
